﻿using RndMaterialDisposalService.Attrbutes;
using RndMaterialDisposalService.Controllers;
using RndMaterialDisposalService.Extensions;
using RndMaterialDisposalService.Models;
using RndMaterialDisposalService.Models.Entitys;
using RndMaterialDisposalService.Repository;
using RndMaterialDisposalService.Services.Interface;
using Microsoft.Data.SqlClient;
using NPOI.POIFS.Crypt.Dsig;
using Masuit.Tools.Core.Net;
using Microsoft.EntityFrameworkCore;
using RndMaterialDisposalService.Models.RequestModel;
using Razor.Templating.Core;
using RndMaterialDisposalService.Helper;
using Newtonsoft.Json;

namespace RndMaterialDisposalService.Services
{
    /// <summary>
    /// 
    /// </summary>
    [NAutowired(Lifecycle.Scoped)]
    public class WorkflowCommon : IWorkflowCommon
    {

        private readonly K2Context k2Context;
        private readonly WorkflowCommonDataContext commonContext;
        private readonly EDPPlatformContext edpContext;
        private EFExtension efExtension;
        private ILogger<WorkflowCommon> logger;
        private readonly UserBaseInforDataContext userBaseInforDataContext;
        private readonly IConfiguration configuration;

        private readonly string encyptUserInfo = "/api/UserLoginInforDecrypt/Encypt";
        private readonly string MailSendUrl = "/api/MailSender/SendMailToQueue";

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_edpContext"></param>
        /// <param name="_logger"></param>
        /// <param name="_k2Context"></param>
        /// <param name="_commonContext"></param>
        /// <param name="_efExtension"></param>
        public WorkflowCommon(EDPPlatformContext _edpContext,
            ILogger<WorkflowCommon> _logger,
            K2Context _k2Context,
            WorkflowCommonDataContext _commonContext,
            EFExtension _efExtension,
            UserBaseInforDataContext _userBaseInforDataContext, 
            IConfiguration _configuration)
        {
            edpContext = _edpContext;
            k2Context = _k2Context;
            efExtension = _efExtension;
            logger = _logger;
            commonContext = _commonContext;
            userBaseInforDataContext = _userBaseInforDataContext;
            configuration = _configuration;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ccList"></param>
        /// <returns></returns>
        public async Task<int> AddCCTask(List<ToReadDto> ccList)
        {
            var sql = "";
            ccList.ForEach(item =>
            {
                sql += " INSERT INTO EDPPLATFORM.dbo.ToRead\r\n" +
                "(FunctionID, FunctionInstanceID, FunctionInstanceUrl, MessageID, UserID, Status, StartDate, ArrivalDate, FinishDate, ExpireDate, Memo, FunctionDescription)\r\n" +
                $"VALUES({item.FunctionID}, {item.FunctionInstanceID}, N'{item.FunctionInstanceUrl}', {item.MessageID}, {item.UserID}, {item.Status}, '{item.StartDate}', '{item.ArrivalDate}', '{item.FinishDate}', '{item.ExpireDate}', N'{item.Memo}', N'{item.FunctionDescription}');\r\n";
            });
            return await edpContext.Database.ExecuteSqlRawAsync(sql);

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="procInstId"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> UpdataWorklistHeader(string procInstId, string url)
        {
            // 处理EDP平台邮件催办
            var sql = $"UPDATE K2.Server.WorklistHeader SET [Data]=@ProcessUrl WHERE ProcInstID=@ProcInstID";
            var newurl = $"{url.Replace("/views/", "/")}?ProcInstID={procInstId}";
            List<SqlParameter> sqlParameters = new List<SqlParameter>
            {
                    new SqlParameter("ProcessUrl", newurl),
                    new SqlParameter("ProcInstID", procInstId)
            };
            return await k2Context.Database.ExecuteSqlRawAsync(sql, sqlParameters);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="procInstId"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<int> GetErrorID(int procInstId)
        {
            var errorlog = await k2Context.ErrorLog.FirstOrDefaultAsync(r => r.ProcInstID == procInstId);
            if(errorlog == null)
            {
                throw new Exception("没有获取到错误信息");
            }
            return errorlog.ID;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="procInstId"></param>
        /// <returns></returns>
        public async Task<int> UpdataCurrentHandler(int procInstId) {
            try
            {
                //查询K2审批人
                string sql = $@"EXEC [dbo].[UP_WorkListItem_GetListByProcInstID] @ProcInstID = {procInstId}";
                var result = efExtension.SqlQuery<WorkItemUser>(k2Context, sql, new List<SqlParameter>());
                var userStr = string.Join(";", result.Select(p => p.ActionerName).ToList());
                var data = await commonContext.ApplicationData.FirstOrDefaultAsync(p => !string.IsNullOrEmpty(p.ProcInstId) && p.ProcInstId.Trim() == procInstId.ToString().Trim());
                if (data != null) {
                    //更新EDP审批人
                    data.CurrentHandler = userStr;
                    return await commonContext.SaveChangesAsync();
                }
            }
            catch (Exception ex)
            {
                logger.LogInformation($"UpdataCurrentHandler  procInstId:{procInstId} , ErrorMessage {ex.Message}");
            }

            return await Task.FromResult(0);
        }

        /// <summary>
        /// 发送邮件通知
        /// </summary>
        /// <param name="list"></param>
        /// <param name="emailHtml"></param>
        public async void EmailSending(List<EmailParameter> list, string emailHtml)
        {
            if (list.Any())
            {
                //用户ID
                List<string> UserIdList = list.Select(a => a.DocumentDistributionUserID).ToList();
                var emailList = userBaseInforDataContext.UserBaseInfor.Where(a => UserIdList.Contains(a.UserId)).ToList();

                if (!string.IsNullOrWhiteSpace(emailHtml))
                {
                    var CommonServiceHost = configuration.GetSection("CommonServiceHost").Value;

                    foreach (var x in list)
                    {
                        var url = $"{CommonServiceHost}{encyptUserInfo}?userID={x.DocumentDistributionUserID}&functionID={x.FunctionId}&procInstID={x.ProcInstId}";
                        //获取加密字符串
                        var response = await HttpHelper.GetAsync<string>(url);

                        string templateData = emailHtml;
                        templateData = templateData.Replace("\r\n", "");
                        templateData = templateData.Replace("\\", "");
                        templateData = templateData.Replace("${subject}", x.Subject);
                        templateData = templateData.Replace("${_Para}", response);
                        templateData = templateData.Replace("[ViteUrl]", x.ViteFormUrl);

                        //配置邮箱参数
                        MailSendModel mailSend = new MailSendModel();
                        mailSend.mailID = 0;
                        mailSend.mailFrom = configuration.GetSection("ApproverSendToEmail").Value;
                        //mailSend.mailTo = "邮箱";
                        mailSend.mailSubject = x.Subject;
                        mailSend.mailBody = templateData;
                        mailSend.isHtml = 1;
                        mailSend.mailStatus = 0;

                        //发送邮件路径
                        var url2 = $"{CommonServiceHost}{MailSendUrl}";

                        //获取人员邮箱
                        if (!string.IsNullOrWhiteSpace(x.DocumentDistributionUserID))
                        {
                            string[] userIdArrar = x.DocumentDistributionUserID.Split(';');

                            foreach (var y in userIdArrar)
                            {
                                var item = emailList.FirstOrDefault(a => a.UserId == y);
                                if (item == null)
                                {
                                    continue;
                                }

                                mailSend.mailTo = item.Email;
                                mailSend.createdDate = DateTime.Now;
                                if (!string.IsNullOrWhiteSpace(mailSend.mailTo))
                                {
                                    await HttpHelper.PostAsync<int>(url2, JsonConvert.SerializeObject(mailSend));
                                }
                            };
                        }
                    };
                }
            }
        }
    }
}
